"""
动态生成用例
"""
from pathlib import Path

import allure
import pytest

from commons import settings
from commons.exchange import Exchange
from commons.files import YamlFile
from commons.models import CaseInfo
from commons.session import Session

import os
import logging

logger = logging.getLogger(__name__)

session = Session()
# yaml文件存放目录
# case_path = Path('../testcases')
_case_path = Path(settings.case_path)
# _case_path = Path(r'D:\PycharmProjects\api_framework\testcases')

exchange = Exchange(settings.extract_path)


# exchange = Exchange(r'D:\PycharmProjects\api_framework\exchange.yaml')
class TestApi:  # 一个可以被pytest识别的类

    @classmethod  # 类方法 实例化之前必须执行
    def find_yaml_case(cls, case_path: Path = _case_path):
        """
        寻找和加载yaml文件
        :return:
        """
        # 搜索指定目录下符合 test_开头&.yaml结尾 的所有文件(**包括子目录)
        yaml_case_list = case_path.glob('**/test_*.yaml')
        for yaml_path in yaml_case_list:
            logger.info(f'load file {yaml_path=}')  # 记录加载的用例文件
            print(yaml_path)
            file = YamlFile(yaml_path)  # 自动读取yaml文件
            case_info = CaseInfo(**file)  # 自动校验yaml格式

            logger.debug(case_info.to_yaml())  # 把case_info转成字符串，然后记录用例内容

            case_func = cls.new_case(case_info)  # 从yaml格式转换为pytest格式
            setattr(cls, f'{yaml_path.name}', case_func)  # 把pytest格式添加到类中（文件名作为用例名）

    @classmethod
    def new_case(cls, case_info: CaseInfo):

        ddt_data = case_info.ddt()
        ddt_title = [data.title for data in ddt_data]

        @allure.epic(settings.allure_epic)
        @allure.feature(case_info.feature)
        @allure.story(case_info.story)
        @pytest.mark.parametrize('case_info', ddt_data, ids=ddt_title)
        def test_func(self, case_info: CaseInfo):
            allure.dynamic.title(case_info.title)
            logger.info(f'用例开始执行：{case_info.title}'.center(80, "="))

            # 变量替换(使用变量需要先修改后再请求接口)
            new_case_info = exchange.replace(case_info)

            logger.info('正在注入变量......')
            logger.debug(f'{exchange.file}')

            # 发送请求
            logger.info('正在请求接口......')
            resp = session.request(**new_case_info.request)
            # 保存变量
            logger.info('正在提取变量......')
            if new_case_info.extract:
                for var_name, extract_info in new_case_info.extract.items():
                    print(var_name, extract_info)
                    # exchange.extract(resp, var_name, extract_info[0], extract_info[1], extract_info[2])
                    exchange.extract(resp, var_name, *extract_info)
            # 断言
            logger.info('正在替换变量......')
            assert_case_info = exchange.replace(case_info)
            # print(assert_case_info)
            logger.info('正在进行断言......')
            assert_case_info.assert_all()
            logger.info(f'用例执行结束：{case_info.title}'.center(80, "="))

        return test_func

# if __name__ == '__main__':
# TestApi.find_yaml_case()  # 运行case.py此文件也可以执行用例
